package com.yix.util;

import lombok.var;
import org.apache.poi.xwpf.usermodel.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WordUtil2 {

    public static ArrayList<String> replaceSS(XWPFDocument docx, HashMap<String, String> bookmark, boolean ShowKey, boolean applyFont) {
        ArrayList<String> returnlist = new ArrayList<String>();
        ArrayList<String> rl;
        //替换段落里面的变量
        rl = replaceInParas(docx, bookmark, ShowKey,applyFont);
        for (int i = 0; i < rl.size(); i++)
            returnlist.add(rl.get(i));
        //替换表格里面的变量
        rl = replaceInTable(docx, bookmark, ShowKey,applyFont);
        for (int i = 0; i < rl.size(); i++)
            returnlist.add(rl.get(i));
        return returnlist;
    }

    /**
     * 替换段落里面的变量
     *
     * @param doc      要替换的文档
     * @param bookmark 参数
     */
    public static ArrayList<String> replaceInParas(XWPFDocument doc, HashMap<String, String> bookmark, boolean ShowKey,boolean applyFont) {
        ArrayList<String> returnlist = new ArrayList<String>();
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph para;
        while (iterator.hasNext()) {
            para = iterator.next();
            ArrayList<String> rl = replaceInPara(para, bookmark, ShowKey,applyFont);
            for (int i = 0; i < rl.size(); i++)
                returnlist.add(rl.get(i));
        }
        return returnlist;
    }

    /**
     * 替换表格里面的变量
     *
     * @param doc      要替换的文档
     * @param bookmark 参数
     */
    public static ArrayList<String> replaceInTable(XWPFDocument doc, HashMap<String, String> bookmark, boolean ShowKey,boolean applyFont) {
        ArrayList<String> returnlist = new ArrayList<String>();
        Iterator<XWPFTable> iterator = doc.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        List<XWPFParagraph> paras;
        while (iterator.hasNext()) {
            table = iterator.next();
            rows = table.getRows();
            for (XWPFTableRow row : rows) {
                cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    paras = cell.getParagraphs();
                    for (XWPFParagraph para : paras) {
                        ArrayList<String> rl = replaceInPara(para, bookmark, ShowKey,applyFont);
                        for (int i = 0; i < rl.size(); i++)
                            returnlist.add(rl.get(i));
                    }
                }
            }
        }
        return returnlist;
    }

    /**
     * 替换段落里面的变量
     *
     * @param para     要替换的段落
     * @param bookmark 参数
     */
    public static ArrayList<String> replaceInPara(XWPFParagraph para, HashMap<String, String> bookmark, boolean ShowKey,boolean applyFont) {
        ArrayList<String> returnlist = new ArrayList<String>();

        List<XWPFRun> runs;
        Matcher matcher;
        String pkey, pval;
        if (matcherL(para.getParagraphText()).find()) {
            runs = para.getRuns();
            for (int i = 0; i < runs.size(); i++) {
                pval = runs.get(i).toString();
                matcher = matcherL(pval);
                if (matcher.find()) {
                    pkey = "Error";
                    while ((matcher = matcherL(pval)).find())//多个标签在1个run中的时候，就会用到这里。
                    {
                        pkey = matcher.group(1);
                        returnlist.add(pkey);
                        if (bookmark == null)
                            pval = matcher.replaceFirst("");
                        else
                            pval = matcher.replaceFirst(String.valueOf(bookmark.get(pkey)));
                    }
                    //直接调用runs.get(i).setText(runText);方法设置文本时，在底层会重新创建一个XWPFRun，把文本附加在当前文本后面，
                    //所以我们不能直接设值，需要先删除当前run,然后再自己手动插入一个新的run。
                    //  记录样式id
                    var run = runs.get(i);
                    var underLine = run.getUnderline();
                    var fontFamliy = run.getFontFamily();
                    var fontSize = run.getFontSize();
                    var isBold = run.isBold();
                    var italic = run.isItalic();
                    if (pval != null && !"null".equals(pval) && bookmark != null) {
                        para.removeRun(i);
                        String[] strs = pval.split("\n");
                        for (int ii = strs.length;ii-->0;) {
                            String s = strs[ii];
                            var newRun = para.insertNewRun(i);
                            newRun.setText(s, 0);
                            //  继承样式
                            newRun.setUnderline(underLine);
                            if(applyFont) {
                                newRun.setFontFamily(fontFamliy);
                                newRun.setFontSize(fontSize);
                            }
                            newRun.setBold(isBold);
                            newRun.setItalic(italic);
                            if(ii!=0) {
                                para.insertNewRun(i).addBreak();//软回车
//                                para.insertNewRun(i).addCarriageReturn();
                            }
                        }
                    }
                }
            }
        }
        return returnlist;
    }

    /**
     * 正则匹配字符串
     *
     * @param str
     * @return
     */
    public static Matcher matcherL(String str) {
        Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }


}
